/*
 * @Author       : mark
 * @Date         : 2020-06-15
 * @copyleft Apache 2.0
 */ 

 #ifndef THREADPOOL_H
 #define THREADPOOL_H
 
 #include <mutex>
 #include <condition_variable>
 #include <queue>
 #include <thread>
 #include <functional>
 #include <assert.h>
 class ThreadPool {
 public:
     explicit ThreadPool(size_t threadCount = 8): pool_(std::make_shared<Pool>()) {
             assert(threadCount > 0);
             for(size_t i = 0; i < threadCount; i++) {
                 std::thread([pool = pool_] {
                     std::unique_lock<std::mutex> locker(pool->mtx);
                     while(true) {
                         if(!pool->tasks.empty()) {
                             auto task = std::move(pool->tasks.front());
                             pool->tasks.pop();
                             locker.unlock();
                             task();
                             locker.lock();
                         } 
                         else if(pool->isClosed) break;
                         else pool->cond.wait(locker);
                     }
                 }).detach();
             }
     }
 
     ThreadPool() = default;
 
     ThreadPool(ThreadPool&&) = default;
     
     ~ThreadPool() {
         if(static_cast<bool>(pool_)) {
             {
                 std::lock_guard<std::mutex> locker(pool_->mtx);
                 pool_->isClosed = true;
             }
             pool_->cond.notify_all();
         }
     }
 
     template<class F>
     void AddTask(F&& task) { //右值引用,在这里是通用引用
         {
             std::lock_guard<std::mutex> locker(pool_->mtx);
             pool_->tasks.emplace(std::forward<F>(task));
         }
         pool_->cond.notify_one(); // 唤醒一个正在等待条件变量的工作线程。
     }
 
 private:
     struct Pool {
         std::mutex mtx; // 互斥锁，保护任务队列
         std::condition_variable cond; // 条件变量，用于线程同步
         bool isClosed; // 标志线程池是否关闭
         std::queue<std::function<void()>> tasks; // 任务队列，存储待执行的任务
     };
     std::shared_ptr<Pool> pool_; // 使用智能指针管理 Pool 对象
 };
 
 
 #endif //THREADPOOL_H